//#include "class_ip_rule.h"
//#include "QDebug"

//class_ip_rule::class_ip_rule()
//{
//    ;
//}

//uint16_t class_ip_rule::calc_cksm(void *pkt, int len) {
//    uint16_t *buf = (uint16_t*)pkt;
//    uint32_t cksm = 0;
//    while (len > 1) {
//        cksm += *buf++;
//        cksm = (cksm >> 16) + (cksm & 0xffff);
//        len -= 2;
//    } if (len) {
//        cksm += *((uint8_t*)buf);
//        cksm = (cksm >> 16) + (cksm & 0xffff);
//    }
//    return (uint16_t)((~cksm) & 0xffff);
//}

//void class_ip_rule::set_psdheader(struct psd_header* ph,struct iphdr *ip, uint16_t tl){
//    ph->saddr=ip->saddr;
//    ph->daddr=ip->daddr;
//    ph->mbz=0;
//    ph->ptcl=6;
//    ph->tcpl=htons(tl);
//}

//int class_ip_rule::cap_start(char *addr[]){
////    if(argc!=3){
////        puts("./main client_ip server_ip");
////        return 0;
////    }
//    int i=0, count=0;
//    pcap_t *descr = NULL;
//    char errbuf[PCAP_ERRBUF_SIZE];
//    char *device;
//    memset(errbuf,0,PCAP_ERRBUF_SIZE);
//    struct bpf_program filter;  //packet filter

//    //生成dh密钥
////    init_numbers(&dh_key);
////    mpz_set_ui(dh_key.base, (unsigned long)2);
////    dh_key.urand = fopen("/dev/urandom","r");

//    // Get the name of the first device suitable for capture
//    if ( (device = pcap_lookupdev(errbuf)) == NULL){
//       fprintf(stderr, "ERROR: %s\n", errbuf);
//       exit(1);
//    }
//    fprintf(stderr ,"Opening device %s\n", device);
//    //Open device in promiscuous mode
//    if ( (descr = pcap_open_live(device, 2048, 1, 500, errbuf)) == NULL){
//        fprintf(stderr, "ERROR: %s\n", errbuf);
//        exit(1);
//    }
//    //set filter src dest host
//    char rule[128] ="(src host 192.168.233.134 and dst host 192.168.233.135) or (src host 192.168.233.135 and dst host 192.168.233.134)";
////    memset(rule,0,128);
////    strncat(rule,"(src host ",10);
////    strncat(rule,addr[1],strlen(addr[1]));
////    strncat(rule," and dst host ",14);
////    strncat(rule,addr[2],strlen(addr[2]));
////    strncat(rule,") or (src host ",15);
////    strncat(rule,addr[2],strlen(addr[2]));
////    strncat(rule," and dst host ",14);
////    strncat(rule,addr[1],strlen(addr[1]));
////    strncat(rule, ")", 1);

//    if(pcap_compile(descr,&filter,rule,1,0)<0){
//        printf("error1\n");
//        return 0;
//    }
//    if(pcap_setfilter(descr,&filter)<0){
//        printf("error2\n");
//        return 0;
//    }
//    ip_rule ip_r;
//    ip_r.p=descr;

//    uchar *addr_cli = (uchar*) "192.168.233.134";
//    uchar *addr_ser = (uchar*) "192.168.233.135";

//    memset(ip_r.client_ip,0,15);
//    memcpy(ip_r.client_ip, addr_cli,strlen((char*)addr_cli));
//    memset(ip_r.server_ip,0,15);
//    memcpy(ip_r.server_ip, addr_ser,strlen((char*)addr_ser));
//    qDebug()<<ip_r.client_ip;
//    qDebug()<<ip_r.server_ip;
//    //Loop forever & call processPacket() for every received packet
//    if ( pcap_loop(descr, -1, processPacket, (u_char *)&ip_r) == -1){
//        fprintf(stderr, "ERROR: %s\n", pcap_geterr(descr) );
//        exit(1);
//    }
//    return 0;
//}

//unsigned char* class_ip_rule::getkey(int k){//扩展为256位密钥
//    unsigned char * r;
//    r=new unsigned char[32];
//    int i;
//    for(i=0;i<32;i++){
//        r[i]=(unsigned char)k;
//    }
//    return r;
//}
//void class_ip_rule::processPacket(u_char *arg, const struct pcap_pkthdr* pkthdr, const u_char * packet){
//    unsigned char server_mac[]={0x00,0x0c,0x29,0xca,0x7d,0x23};
//    unsigned char client_mac[]={0x00,0x0c,0x29,0xda,0xaa,0x8c};
//    unsigned char my_mac[]={0x00,0x0c,0x29,0x41,0x08,0x8a};//这个地方的三处要改

//    struct ether_header *ethernet;
//    struct iphdr *ip;
//    struct tcphdr *tcp;

//    char srcip_str[16];
//    memset(srcip_str,0,16);
//    ip_rule * ip_r=(ip_rule*)arg;

//    ethernet = (struct ether_header*)(packet);  //ethernet header
//    ip = (struct iphdr*)(packet + ETHER_HDR_LEN);   //ip head
//    tcp = (struct tcphdr*)(packet + ETHER_HDR_LEN+ sizeof(struct iphdr));   //tcp head

//    int hdr_len = ETHER_HDR_LEN + sizeof(struct iphdr) + sizeof(struct tcphdr)+12;//报文头长度
//    int dl = pkthdr->len - hdr_len;//数据报实际长度减去报文头长度，即报文中data的长度

//    inet_ntop(AF_INET,&(ip->saddr),srcip_str,16);
//    //src mac
//    memcpy(ethernet->ether_shost,my_mac,6);//将源mac改为中间人mac

////    if(memcmp(srcip_str, ip_r->client_ip, strlen(srcip_str))==0)//来自client
////    {
////        QByteArray tmpq;
////        int i;
////        for(i = 66 ;i < pkthdr->len ;i++)
////        {
////            tmpq.append(packet[i]);
////        }
////        QString tmpstr = QString::fromUtf8(tmpq);
////        qDebug()<<tmpstr;
////        memcpy(ethernet->ether_dhost ,server_mac ,6);
////    }
////    else//来自server
////    {
////        qDebug()<<"ans";
////    }
////    pcap_sendpacket(ip_r->p, packet, pkthdr->len);//pkthdr->len不变


//    if(memcmp(srcip_str, ip_r->client_ip, strlen(srcip_str))==0)//client->server
//    {//client

//        int lengthA;//原报文长度
//        int lengthB;//修改后报文长度

//        lengthA=dl;

//        //提取消息部分，假定ack消息自动转发
//        QByteArray tmpq;
//        int i;
//        for(i = 66 ;i < pkthdr->len ;i++)
//        {
//            tmpq.append(packet[i]);
//        }
//        QByteArray tmpq2=QByteArray::fromBase64(tmpq);//base64解码
//        QString tmpstr = QString::fromUtf8(tmpq2);//utf-8解码，为了支持中文用户名
//        qDebug()<<tmpstr;


//        //这个消息的头部有两种可能，request或者data
//        //对于请求登录消息，需要修改KA，对于data消息，需要显示在界面上（先在debug上显示）

//        QStringList list;
//        list=tmpstr.split("-");//以"-"做分隔

//        if(list.at(0)=="request"){//packet[hdr_len]="request-\`username\`-\`password\`-\r`c_rsa_e\`-\`c_rsa_n\`-\`g\`-\`p\`-\`Ya\`"，截到公钥报，修改公钥和校验码再发出
//            //mpz_set_str(key_from_c ,packet + hdr_len + 3 ,16);//这里要改，提取packet里的数据

//            //char* tmp;
//            //memcpy(tmp, packet + hdr_len, dl)//读

//            //g^(at)
//            //
//            //T=g^(t)
//            //
//            //send T to server

//            QString username;
//            QString passwordhash;
//            QString rsa_e;
//            QString rsa_n;
//            QString g0;
//            QString p0;
//            QString KA0;

//            username=list.at(1);
//            passwordhash=list.at(2);
//            rsa_e=list.at(3);
//            rsa_n=list.at(4);
//            g0=list.at(5);
//            p0=list.at(6);
//            KA0=list.at(7);

//            int g=g0.toInt();
//            int p=p0.toInt();
//            int KA=KA0.toInt();

//            DH1.g=g;
//            DH1.p=p;
//            DH1.KA=KA;
//            DH1.server_get_key();//生成KM = DH1.KB = DH2.K1
//            DH2.g=g;
//            DH2.p=p;
//            DH2.KA=DH1.KB;

//            QString rslt_tmp=list.at(0)+"-"+list.at(1)+"-"+list.at(2)+"-"+list.at(3)+"-"+list.at(4)+"-"+list.at(5)+"-"+list.at(6)+"-"+QString::number(DH2.KA)+"-1-";
//            //KA->KM
//            QByteArray rslt_bt=rslt_tmp.toUtf8().toBase64();

//            lengthB=rslt_bt.size();//字节数
//            char *rslt=rslt_bt.data();

//           //修改数据内容
//           memcpy(packet+hdr_len,rslt,lengthB);

//           //修改长度
//           //待定

//           qDebug()<<"======recieve  from client ===============";
//           qDebug()<<"username:"<<username;
//           qDebug()<<"password hash:"<<passwordhash;
//           qDebug()<<"rsa_e:"<<rsa_e<<" rsa_n:"<<rsa_n;
//           qDebug()<<"g:"<<g;
//           qDebug()<<"p:"<<p;
//           qDebug()<<"KA:"<<KA;
//           qDebug()<<"KM:"<<DH1.KB;
//           qDebug()<<"前后字节差："<<lengthB-lengthA;
//           qDebug()<<"发送的字符串："<<rslt_tmp;
//           qDebug<<"============================================";

//            memcpy(ethernet->ether_dhost,server_mac,6);//将目的mac改为服务器
//            //T->char*

//            //memcpy(packet+hdr_len+3,pub,sizeof(pub));//这里改，将public_key替换报文对应内容
//            //recalculate the checksum
//            uint16_t tcp_len = pkthdr->len - ETHER_HDR_LEN - sizeof(struct iphdr);
//            unsigned char * data_for_checksum = (unsigned char*)malloc(tcp_len + sizeof(struct psd_header));
//            struct psd_header ph;
//            bzero(data_for_checksum, tcp_len + sizeof(ph));
//            set_psdheader(&ph, ip, tcp_len);
//            memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
//            tcp->check = 0;
//            memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
//            uint16_t cs=calc_cksm(data_for_checksum, tcp_len + sizeof(ph));
//            tcp->check=cs;

//        }else if(list.at(0)=="data"){
//            //decrypt
////            char *buff=(char*)(packet+hdr_len);//正文内容存在buff里
////            char *plain=(char*)malloc(dl - 48);//dl是报文正文长度
////            bzero(plain, sizeof(buff));

//            //消息格式data-用户名-原消息长度-经过处理的密文（只进行了aesgcm加密),用DH1.K解密
//             qDebug()<<"========recv msg==========";
//             QString username;
//             int length;
//             username=list.at(1);
//             QString s;
//             s=list.at(2);
//             length=s.toInt();
//             qDebug()<<"username:"<<username;
//             qDebug()<<"length:"<<length;
//             int readbuflenth=dl;//数据的长度

//             //aes解密
//             QString begin;//计算消息头的长度，AES密文的长度
//             begin="data-"+username+"-"+list.at(2)+"-";
//             QByteArray b;
//             b=begin.toUtf8();
//             qDebug()<<"begin:"<<begin;
//             qDebug()<<"b length:"<<b.length();
//             int beginlength=b.length()+hdr_len;//AES密文起始位置
//             int aescipherlength;
//             aescipherlength=readbuf.length()-b.length();//aes密文长度
//             QByteArray aescipherbytearray;
//             int i;
//             for(i=beginlength;i<beginlength+aescipherlength;i++){
//                 aescipherbytearray.append(packet[i]);
//             }
//             qDebug()<<"数据长度："<<readbuflenth;
//             qDebug()<<"aescipherlength"<<aescipherbytearray.length();
//             aes_gcm aesg(aesg.getgcmchar(getkey(DH1.K),32));
//             aesg.input2=aescipherbytearray;
//             aesg.aes_decrypt();
//             QString aesoutput;
//             aesoutput=aesg.output2;
//             qDebug()<<"解密得到的原文："<<aesoutput;



//             //解密后的数据提取原文，进行MD5和签名验证
//             QString msg;
//             msg=aesoutput.mid(0,length);
//             QString uistring;//要显示的字符串
//             uistring=username+":"+msg;
//             qDebug()<<"显示："<<uistring;
//             qDebug()<<"===========complete=============";


//            //add(16)+iv(12)+tag(16)+data
//            //unsigned char iv[12],add[16],tag[16];
//            //memcpy(add,buff+4,16);
//            //memcpy(iv,buff+16+4,12);
//            //memset(tag,0,16);
//            //int tmp=aes_gcm_ad(key_value, 32,iv, 12,buff+44+4, dl-44-4,add, 16,tag, plain);//读内存中data

//            //用memcpy或者append读内存，利用K1解密得到data

//            //encrypt
//            //bzero(key_string, sizeof(key_string));
//            //mpz_get_str(key_string, 16, dh_key.key_for_server);
//            //memcpy(key_value, str2hex(key_string), sizeof(key_value));
//            //tmp=aes_gcm_ae(key_value, 32,iv,12,plain,dl-48,add, 16,buff+44+4, tag);//写内存中data
//            //packet+hdr_len+"data"`add`[16]`iv`[12]`tag`[16]+`data`

//            //将data重新加密并写入内存

//            //recalculate the checksum
//            uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
//            unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
//            struct psd_header ph;
//            bzero(data_for_checksum, tcp_len+sizeof(ph));
//            set_psdheader(&ph, ip, tcp_len);
//            memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
//            tcp->check=0;
//            memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
//            uint16_t cs=calc_cksm(data_for_checksum, tcp_len+sizeof(ph));
//            tcp->check=cs;
//        }
//        memcpy(ethernet->ether_dhost,server_mac,6);//将发送方MAC地址改写为本机
//    }else{//server->client

//        int lengthA;//原报文长度
//        int lengthB;//修改后报文长度

//        lengthA=dl;

//        //提取消息部分，假定ack消息自动转发
//        QByteArray tmpq;
//        int i;
//        for(i = 66 ;i < pkthdr->len ;i++)
//        {
//            tmpq.append(packet[i]);
//        }
//        QByteArray tmpq2=QByteArray::fromBase64(tmpq);//base64解码
//        QString tmpstr = QString::fromUtf8(tmpq2);//utf-8解码，为了支持中文用户名
//        qDebug()<<tmpstr;


//        //这个消息的头部有三种可能，或者ok，data，error,先只考虑前两种
//        //对于允许登录消息&用户列表信息：ok-服务器rsa公钥e-n-KB-当前人数-用户名1-用户名2....，需要修改KB为KM
//        //对于data消息，需要显示在界面上（先在debug上显示）

//        QStringList list;
//        list=tmpstr.split("-");//以"-"做分隔

//        //server
//        if(list.at(0)=="ok"){//允许登录消息
////            mpz_set_str(key_from_s ,packet + hdr_len + 3 ,16);//这里改，读内存，提取服务器的Y
////            //g^(bt)
////            unsigned char pub[64];
////            //mpz_get_str(pub,16,dh_key.public_key);
////            memcpy((uchar*)packet+hdr_len+3,pub,sizeof(pub));//替换自己的密钥，要改，然后写内存


//            QString rsa_e;
//            QString rsa_n;
//            QString KB0;

//            rsa_e=list.at(1);
//            rsa_n=list.at(2);
//            KB0=list.at(3);

//            int KB=KB0.toInt();

//            DH2.KB=KB;
//            DH2.client_get_key();//生成K2,已知K1,K2,将DH1.KB（KM）代替KB传回去

//            QString rslt_tmp;//KB->KM
//            int i;
//            for(i=0;i<list.count();i++){
//               if(i==3){
//                    rslt_tmp+=QString::number(DH1.KB)+"-";
//               }else{
//                   rslt_tmp+=list.at(i)+"-";
//               }
//            }
//            QByteArray rslt_bt=rslt_tmp.toUtf8().toBase64();

//            lengthB=rslt_bt.size();//字节数
//            char *rslt=rslt_bt.data();

//           //修改数据内容
//           memcpy(packet+hdr_len,rslt,lengthB);

//           //修改长度
//           //待定

//           qDebug()<<"======recieve  from server ===============";
//           qDebug()<<"rsa_e:"<<rsa_e<<" rsa_n:"<<rsa_n;
//           qDebug()<<"KB:"<<KB;
//           qDebug()<<"K1:"<<DH1.K;
//           qDebug()<<"K2:"<<DH2.K;
//           qDebug()<<"前后字节差："<<lengthB-lengthA;
//           qDebug()<<"发送的字符串："<<rslt_tmp;
//           qDebug<<"============================================";

//            //recalculate the checksum
//            uint16_t tcp_len = pkthdr->len - ETHER_HDR_LEN - sizeof(struct iphdr);
//            unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
//            struct psd_header ph;
//            bzero(data_for_checksum, tcp_len+sizeof(ph));
//            set_psdheader(&ph, ip, tcp_len);
//            memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
//            tcp->check=0;
//            memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
//            unsigned short cs=calc_cksm(data_for_checksum, tcp_len+sizeof(ph));
//            tcp->check=cs;
//        }else if(list.at(0)=="data"){//建议改协议前缀data
//            //decrypt
////            char *buff=(char*)packet+hdr_len;
////            char *plain=(char*)malloc(长度);
////            bzero(plain, sizeof(buff));

//            //消息格式data-用户名-原消息长度-经过处理的密文（只进行了aesgcm加密),用DH2.K解密
//             qDebug()<<"========recv msg==========";
//             QString username;
//             int length;
//             username=list.at(1);
//             QString s;
//             s=list.at(2);
//             length=s.toInt();
//             qDebug()<<"username:"<<username;
//             qDebug()<<"length:"<<length;
//             int readbuflenth=dl;//数据的长度

//             //aes解密
//             QString begin;//计算消息头的长度，AES密文的长度
//             begin="data-"+username+"-"+list.at(2)+"-";
//             QByteArray b;
//             b=begin.toUtf8();
//             qDebug()<<"begin:"<<begin;
//             qDebug()<<"b length:"<<b.length();
//             int beginlength=b.length()+hdr_len;//AES密文起始位置
//             int aescipherlength;
//             aescipherlength=readbuf.length()-b.length();//aes密文长度
//             QByteArray aescipherbytearray;
//             int i;
//             for(i=beginlength;i<beginlength+aescipherlength;i++){
//                 aescipherbytearray.append(packet[i]);
//             }
//             qDebug()<<"数据长度："<<readbuflenth;
//             qDebug()<<"aescipherlength"<<aescipherbytearray.length();
//             aes_gcm aesg(aesg.getgcmchar(getkey(DH2.K),32));
//             aesg.input2=aescipherbytearray;
//             aesg.aes_decrypt();
//             QString aesoutput;
//             aesoutput=aesg.output2;
//             qDebug()<<"解密得到的原文："<<aesoutput;



//             //解密后的数据提取原文，进行MD5和签名验证
//             QString msg;
//             msg=aesoutput.mid(0,length);
//             QString uistring;//要显示的字符串
//             uistring=username+":"+msg;
//             qDebug()<<"显示："<<uistring;
//             qDebug()<<"===========complete=============";


//            //add(16)+iv(12)+tag(16)+data
//            //unsigned char iv[12],add[16],tag[16];
//            //memcpy(add,buff+4,16);
//            //memcpy(iv,buff+16+4,12);
//            //memset(tag,0,16);
//            //int tmp=aes_gcm_ad(key_value, 32,iv, 12,buff+44+4, dl-44-4,add, 16,tag, plain);

//            //memcpy或者append读内存，解密

//            printf("[server]%s",plain);//这里改成信号，随时发送到界面

//            //encrypt
//            //bzero(key_string, sizeof(key_string));
//            //mpz_get_str(key_string, 16, dh_key.key_for_client);
//            //memcpy(key_value, str2hex(key_string), sizeof(key_value));
//            //tmp=aes_gcm_ae(key_value, 32,iv,12,plain,dl-48,add, 16,buff+44+4, tag);

//            //用K2加密，写内存

//            //recalculate the checksum
//            uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
//            unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
//            struct psd_header ph;
//            bzero(data_for_checksum, tcp_len+sizeof(ph));
//            set_psdheader(&ph, ip, tcp_len);
//            memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
//            tcp->check=0;
//            memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
//            uint16_t cs=calc_cksm(data_for_checksum, tcp_len+sizeof(ph));
//            tcp->check=cs;
//        }
//        memcpy(ethernet->ether_dhost,client_mac,6);
//    }
//    pcap_sendpacket(ip_r->p,packet,pkthdr->len);//pkthdr->len不变
//    return;
//}


